package com.zqh.messagemq.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * @Description :
 * @Author :kono淇杭哒、
 * @Create 2021-12-09 23:04
 */
@Component("rabbitMqPublisher")
@Slf4j
public class RabbitMqPublisher{
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 默认的ttl为半小时
     */
    private final Integer default_ttl = 30 * 60 * 1000;

    public void publishDelayedMessage(String msg) {
        publishDelayedMessage(msg,default_ttl);
    }

    public void publishDelayedMessage(String msg, Integer ttl) {
        Message message = MessageBuilder.withBody(msg.getBytes(StandardCharsets.UTF_8)).setHeader("x-delay", ttl).build();
        //消息工D，需要封装到CorrelationData中
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        // 添加confirm-callback
        correlationData.getFuture().addCallback(
                //这里是mq接收到了消息然后回调返回的结果，有交换机成功接收消息和接收失败两种情况
                result -> {
                    if(result.isAck()){
                        // 3.1.ack，消息成功
                        log.debug("消息发送成功, ID:{}", correlationData.getId());
                    }else{
                        // 3.2.nack，消息失败
                        log.error("消息发送失败, ID:{}, 原因{}",correlationData.getId(), result.getReason());
                    }
                },
                //这里是连消息还没发送到mq就失败的情况
                ex -> log.error("消息发送异常, ID:{}, 原因{}",correlationData.getId(),ex.getMessage())
        );
        //发送消息
        rabbitTemplate.convertAndSend(Consumer.DELAYED_EXCHANGE_NAME,Consumer.DELAYED_ROUTING_KEY,msg,
                correlationData2 -> {
                    correlationData2.getMessageProperties().setDelay(ttl);
                    return correlationData2;
                },correlationData);

        System.out.println(LocalDateTime.now());
        System.out.println("发送延迟消息成功：" + msg);
        log.debug("发送延迟消息成功："+msg);
    }

}
